#include "voda.h"
#include "script.h"
#include "thread_pool.h"
#include "application.h"

namespace voda
{
	boost::shared_ptr<application> application::create (boost::shared_ptr<thread_pool> const & pool, boost::function<void(application*)> const & deleter)
	{
		if (deleter)
		{
			return boost::shared_ptr<application> (new application (pool), deleter);
		}
		else
		{
			return boost::shared_ptr<application> (new application (pool));
		}
	}

	application::application (boost::shared_ptr<thread_pool> const & pool)
		: pool_ (pool)
		, io_service_ (pool->get_io_service ())
		, strand_ (io_service_)
		, rt_ ()
	{
	}

	application::~application (void)
	{
	}

	void application::post (boost::function<void()> const & handler)
	{
		strand_.post (
			boost::bind (
				&application::call_handler, 
				shared_from_this(), 
				handler
			)
		);
	}

	void application::io_post (boost::function<void()> const & handler)
	{
		io_service_.post (
			boost::bind (
				&application::call_handler, 
				shared_from_this(), 
				handler
			)
		);
	}

	boost::asio::io_service & application::get_io_service ()
	{
		return io_service_;
	}

	boost::asio::io_service::strand & application::get_strand ()
	{
		return strand_;
	}

	boost::shared_ptr<iscript> application::create_script (boost::shared_ptr<io> const & p)
	{
		return script::create (
			shared_from_this (),
			boost::bind (
				&application::script_deleter, 
				shared_from_this (), 
				_1
			)
		);
	}

	void application::script_deleter (script *pscript)
	{
		delete pscript;
	}

	void application::call_handler (boost::function<void()> const & fn)
	{
		if (fn) {
			fn ();
		}
	}

	runtime const & application::get_runtime () const 
	{
		return rt_;
	}
}